/*
 * SoundManager.h
 *
 *  Created on: 2009/01/31
 *      Author: Yongshik Cho
 */

#ifndef SOUNDMANAGER_H_
#define SOUNDMANAGER_H_

#include <vector>

#include "core/Prerequisites.h"
#include "core/ISingleton.h"
#include "Sound.h"
#include <vorbis/vorbisfile.h>

#include "sqplus/sqplus.h"
using namespace SqPlus;

#ifdef __BIG_ENDIAN__
#	define ENDIAN 1
#else
#	define ENDIAN 0
#endif

class Audible;

class SoundManager : public ISingleton<SoundManager>
{
public:
	static const String _EXT_OGG;
	static const String _EXT_MP3;
	static const String _EXT_WAV;

	static const uint32 _BUFFER_SIZE 			= (4096 * 8);

public:
	SoundManager();
	virtual ~SoundManager();

public:
	static SoundManager& GetInstance()
	{
		assert(m_pInstance);
		return *m_pInstance;
	}
	static SoundManager* GetInstancePtr()
	{
		return m_pInstance;
	}

public:
	virtual Sound* load(const String& p);
	inline const uint32 getSoundCount() { return (uint32)mSounds.size(); }

	static int32 queueStream(Audible* sound);
	static void disposeSound(Sound* sound);

private:
	Sound* isExists(const String& p);
	Sound* loadSound(const String& p);
	Sound* loadOgg(const String& p);
	Sound* loadMp3(const String& p);

	static uint32 oggReadDataFn(void *ptr			/* ptr to the data that the vorbis files need*/,
			  uint32 byteSize	/* how big a byte is*/,
			  uint32 sizeToRead /* How much we can read*/,
			  void *source	/* this is a pointer to the data we passed into ov_open_callbacks (our SOggFile struct*/);

	static int32 oggSeekFn(void *source		/*this is a pointer to the data we passed into ov_open_callbacks (our SOggFile struct*/,
			   ogg_int64_t offset	/*offset from the point we wish to seek to*/,
			   int32 whence			/*where we want to seek to*/);

	static int32 oggCloseFn(void *source /*this is a pointer to the data we passed into ov_open_callbacks (our SOggFile struct*/);

	static long oggTellFn(void *source /*this is a pointer to the data we passed into ov_open_callbacks (our SOggFile struct*/);


private:
	vector<Sound*>	mSounds;
};

//must be declared here
DECLARE_INSTANCE_TYPE(SoundManager)

#endif /* SOUNDMANAGER_H_ */
